fix: scale timeline keyframe virtualization with scroll viewport height#9712
Open
tt-dmi wants to merge 1 commit into
Open
fix: scale timeline keyframe virtualization with scroll viewport height#9712tt-dmi wants to merge 1 commit into
tt-dmi wants to merge 1 commit into
Conversation
👷 Deploy request for label-studio-docs-new-theme pending review.Visit the deploys page to approve it
|
👷 Deploy request for heartex-docs pending review.Visit the deploys page to approve it
|
✅ Deploy Preview for label-studio-storybook ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for label-studio-playground ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reason for change
This PR fixes a Video timeline rendering issue where keyframe diamonds stop appearing for
regions further down the timeline, even though the region rows themselves render.
Observed behavior:
VideoRectangletask with many regions, scrolling the timeline reveals rows whoselabels render but whose keyframe diamond track is empty
<Video timelineHeight="…" />does not fix it — the cap is independent ofthe configured timeline height
This appears related to:
Root cause:
KeypointsVirtual(the inner virtualized list of keyframe rows) computed its renderwindow from a hardcoded
165px instead of the scroll container's actual height:extra = 5 buffer ≈ 11 rows total
renderable={false} from the parent and their keyframes are skipped
Solution:
call already provides width for framesInView)
reproduces the prior behavior exactly
What changed
In web/libs/editor/src/components/Timeline/Views/Frames/Frames.tsx:
(Math.ceil(viewHeight / height) - 1)
Net diff: 6 insertions / 4 deletions in a single file.
Screenshots / Representation
Before — scrolled to the bottom of a 28-region video timeline; lower rows show labels but
no keyframes:
After — same task, same scroll position; every visible row renders its keyframes:
Rollout strategy
No feature flag.
This is a direct bug fix to the Video timeline render-window calculation.
Testing
Manual verification performed locally on Label Studio 1.23.0:
for ~17 of them
timelineHeight
Additional validation performed:
they always fit inside both the original 165 px window and the measured viewport
web/libs/editor/src/components/Timeline/Views/Frames/Frames.test.tsx still pass — the
useResizeObserver mock returns { width: 400 }, so scrollableHeight is undefined and the
?? 165 fallback path reproduces the prior behavior
Happy to add a unit test that asserts more rows become renderable as the observed height
grows — let me know if you'd like that in this PR or a follow-up.
Risks
Low.
Potential risks:
viewport, where previously they were silently capped at ~11; tasks with hundreds of
regions and a tall timelineHeight will paint more keyframes per scroll position than they
did before
uses the ?? 165 fallback for a single frame before the observer fires
Risk mitigations:
public API or prop changes on
environment without ResizeObserver
Reviewer notes
The most important logic is in:
Please review:
measurement to feed virtualization (it's the same element already used for framesInView)
General notes
The 165 was a magic constant approximating ~6 visible rows × 24 px row height + slack. It
predates the useResizeObserver call that the same component now uses for horizontal
framesInView. This fix simply lets keyframe virtualization read from the same
observation.